home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 106_01 / stdio.src < prev    next >
Text File  |  1980-07-08  |  5KB  |  184 lines

  1. /*                stdio.src
  2.  
  3.     Copyright (C) 1980, M J Maney
  4.  
  5.     First created    3/15/80
  6.     Last revised    4/19/80 1:45
  7.  
  8.     This file defines some useful functions that are designed to help
  9.     make BDS C programs running under CP/M pretend that they're
  10.     running in a nicer environment (like UNIX, ha-ha). It makes it
  11.     easier to setup and use STDIN and STDOUT directed IO, and
  12.     although you can't just assume that they're there as you can
  13.     with UNIX C, at least you don't have to put in code to parse
  14.     the command line into each program you write: just use the
  15.     functions here.
  16. */
  17.  
  18.  
  19. #include "csym.lib"
  20. #include "stdio.lib"
  21.  
  22. #define ESCAPE '\\'
  23.  
  24.  
  25. /* stdopen parses the command line arguments looking for arguments that
  26.     begin with "<" or ">", which are respectively taken to be the
  27.     filenames for STDIN and STDOUT. The defaults are to use the
  28.     console for both STDIN and STDOUT. Any argument beginning with
  29.     "<" or ">" is effectively removed from the argument list (by
  30.     moving pointers in argv[] and decreasing argc)...if your program
  31.     wants to get an argument beginning with "<" or ">", you must
  32.     type it as "\<" or "\>", and stdopen will replace the escape
  33.     sequence in the strings, but will not "use" those arguments
  34.     for IO assignment. If you want to pass arguments beginning with
  35.     "\", you must type "\\" to escape the escape character.
  36.  
  37.     NB: the escape character is ONLY significant to stdopen() in the
  38.     FIRST character position of an argument.
  39.  
  40.     If the "filter" argument is true, and stdopen finds a STDIN arg,
  41.     but does not find one for STDOUT, then an amazing thing happens:
  42.     a STDOUT file is created with the same drive and name as STDIN,
  43.     but a type of "$$$". Then, when stdclose is called to close
  44.     the files, the following occurs:
  45.         1)    STDIN is closed
  46.         2)    STDOUT is closed
  47.         3)    if both closes were OK, then
  48.             STDIN is deleted, and
  49.             STDOUT is renamed to the original (STDIN) filename
  50.         else an error message is printed, and any active SUBMIT file
  51.             that may be present is deleted (to break out of any
  52.             pipeline that may be running)
  53.  
  54.     Stdopen returns ERR if something goes awry. If everything is
  55.     ok, it will return YES or NO, depending on whether STDIN is a
  56.     file or not (NO if its left attatched to the console). This
  57.     provides a mechanism for programs using stdopen to determine
  58.     whether they're talking to the console or a file when they
  59.     get input from STDIN, which is often useful, without the program
  60.     needing to know about _stdin and the like.
  61. */
  62.  
  63. int stdopen(argc,argv,filter)
  64. int    *argc;        /* NB that argc MUST be passed by reference */
  65. char    *argv[];
  66. char    filter;
  67.     {
  68.     char    trouble,haveinp,haveout;    /* flags */
  69.     char    c;
  70.     int    i,j;
  71.  
  72.     trouble=haveinp=haveout=NO;
  73.     _filter=NO;
  74.     _stdin=_stdout=CONSOLE;
  75.     i=1;
  76.     while (i<*argc)
  77.         switch(c=*argv[i]) {
  78.         case '<' :
  79.         case '>' :
  80.             if (c=='<') {
  81.                 if (haveinp)    /* more than one STDIN arg */
  82.                     trouble=YES;
  83.                 else
  84.                     strcpy(_inpname,argv[i]+1);
  85.                 haveinp=YES;
  86.                 }
  87.             else {
  88.                 if (haveout)    /* more than one STDOUT arg */
  89.                     trouble=YES;
  90.                 else
  91.                     strcpy(_outname,argv[i]+1);
  92.                 haveout=YES;
  93.                 }
  94.             for (j=i+1 ; j<*argc ; j++)
  95.                 argv[j-1]=argv[j];
  96.             (*argc)--;
  97.             break;
  98.         case ESCAPE :
  99.             strcpy(argv[i],argv[i]+1);
  100.             /* fall through to increment i */
  101.         default :
  102.             i++;
  103.             }    /* end of switch, also end of while */
  104.  
  105.     if (trouble) {
  106.         puts("\nTrouble: multiple STDIN or STDOUT args. Continue ?");
  107.         if (toupper(getchar())!='Y')
  108.             exit();
  109.         else
  110.             trouble=NO;
  111.         }
  112.  
  113.     if (haveinp && !haveout && filter) {
  114.         strcpy(_outname,_inpname);
  115.         for (i=0 ; _outname[i]!='\0' && _outname[i]!='.' ; i++)
  116.             ;
  117.         strcpy(_outname+i,".$$$");
  118.         haveout=_filter=YES;
  119.         }
  120.  
  121.     if (haveinp)
  122.         if ((_inpfd=fopen(_inpname,_inpbuf))==ERR) {
  123.             puts("\nCannot open STDIN: ");
  124.             printf("%s",_inpname);
  125.             return ERR;
  126.             }
  127.         else
  128.             _stdin=FILE;
  129.  
  130.     if (haveout)
  131.         if ((_outfd=fcreat(_outname,_outbuf))==ERR) {
  132.             puts("\nCannot create STDOUT: ");
  133.             printf("%s",_outname);
  134.             return ERR;
  135.             }
  136.         else
  137.             _stdout=FILE;
  138.  
  139.     return (_stdin==CONSOLE ? YES : NO);
  140.     }
  141.  
  142.  
  143. /* stdclose is the function that closes STDIN and STDOUT files if needed,
  144.     so that tou don't have to think about which might be files and
  145.     which not. Also continues the idea of hiding tthese little
  146.     peculiararities from your program. This is where that _filter
  147.     flag is put to good use, too.
  148. */
  149.  
  150. int stdclose()
  151.     {
  152.     int    flag;
  153.  
  154.     if (_stdin==FILE) {
  155.         flag=(close(_inpfd)==ERR);
  156.         _stdin=CONSOLE;
  157.         }
  158.     else
  159.         flag=TRUE;
  160.  
  161.     if (_stdout==FILE) {
  162.         putc(EOT,_outbuf);
  163.         fflush(_outbuf);
  164.         flag|=(close(_outfd)==ERR);
  165.         _stdout=CONSOLE;
  166.         }
  167.     else
  168.         flag=TRUE;
  169.  
  170.     if (_filter)
  171.         if (flag) {
  172.             puts("\nStdio close error");
  173.             unlink("A:$$$.SUB");
  174.             return ERR;
  175.             }
  176.         else {
  177.             unlink(_inpname);
  178.             rename(_outname,_inpname);
  179.             }
  180.  
  181.     _filter=NO;
  182.     return OK;
  183.     }
  184.